function(get_current_directory_name RESULT)
    string(REGEX REPLACE ".*/\(.*\)" "\\1" OUTPUT ${CMAKE_CURRENT_SOURCE_DIR})
    set(${RESULT} ${OUTPUT} PARENT_SCOPE)
endfunction()

function(get_directory_name DIRECTORY_NAME RESULT)
    string(REGEX REPLACE ".*/\(.*\)" "\\1" OUTPUT ${DIRECTORY_NAME})
    set(${RESULT} ${OUTPUT} PARENT_SCOPE)
endfunction()

function(create_gtest TEST_NAME TEST_FILES DEPENDENT_SOURCE_FILES DEPENDENT_LIBS)
    if("${TEST_FILES}" STREQUAL "")
        return()
    endif()
    List(LENGTH TEST_FILES TEST_FILE_COUNT)
    set(SHOULD_CREATE_TEST OFF)
    if(TEST_FILE_COUNT EQUAL 2)
        List(GET TEST_FILES 1 TEST_2ND_FILE)
        if(NOT "${TEST_2ND_FILE}" STREQUAL "")
            set(SHOULD_CREATE_TEST ON)
        endif()
    elseif(TEST_FILE_COUNT GREATER 1)
        set(SHOULD_CREATE_TEST ON)
    endif()

    if(SHOULD_CREATE_TEST)
        message(STATUS "Create gtest:${TEST_NAME}.")
        #create test executable
        add_executable(${TEST_NAME} ${TEST_FILES})
        #set test dependent lib name
        set(TEST_DEPENDENCIES_LIB "${TEST_NAME}Dependency")
        #create test dependent lib
        if(NOT "${DEPENDENT_SOURCE_FILES}" STREQUAL "")
            add_library(${TEST_DEPENDENCIES_LIB} STATIC EXCLUDE_FROM_ALL ${DEPENDENT_SOURCE_FILES})
            #force cmake output lib to ${CMAKE_BINARY_DIR}/Test/lib
            set_target_properties(${TEST_DEPENDENCIES_LIB} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY  ${CMAKE_BINARY_DIR}/Test/lib)
            set_target_properties(${TEST_DEPENDENCIES_LIB} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/Test/lib)
            set_target_properties(${TEST_DEPENDENCIES_LIB} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/Test/lib)
            set_target_properties(${TEST_DEPENDENCIES_LIB} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_BINARY_DIR}/Test/lib)
            set_target_properties(${TEST_DEPENDENCIES_LIB} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_BINARY_DIR}/Test/lib)
            set_target_properties(${TEST_DEPENDENCIES_LIB} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Test)
            set_target_properties(${TEST_DEPENDENCIES_LIB} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/Test)
            set_target_properties(${TEST_DEPENDENCIES_LIB} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/Test)
            set_target_properties(${TEST_DEPENDENCIES_LIB} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_BINARY_DIR}/Test)
            set_target_properties(${TEST_DEPENDENCIES_LIB} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_BINARY_DIR}/Test)
            #force the lib full name is lib${TEST_DEPENDENCIES_LIB}
            set_target_properties(${TEST_DEPENDENCIES_LIB} PROPERTIES PREFIX "lib")
            #force debug the lib postfix is "_d"
            set_target_properties(${TEST_DEPENDENCIES_LIB} PROPERTIES DEBUG_POSTFIX "_d")
            #force build the lib before test executable
            add_dependencies(${TEST_NAME} ${TEST_DEPENDENCIES_LIB})
            #dependent the lib link test executable dependent libs
            target_link_libraries(${TEST_DEPENDENCIES_LIB} ${DEPENDENT_LIBS})
            #add the lib to test executable dependent libs
            List(APPEND DEPENDENT_LIBS "${TEST_DEPENDENCIES_LIB}")
        endif()
        #use pthread or mt
        if(MSVC)
            set_property(TARGET ${TEST_NAME} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
            target_link_libraries(${TEST_NAME} PRIVATE GTest::gtest ${DEPENDENT_LIBS})
        else()
            target_link_libraries(${TEST_NAME} PRIVATE GTest::gtest pthread ${DEPENDENT_LIBS})
        endif()
        #force cmake output test executable to ${CMAKE_BINARY_DIR}/Test
        set_target_properties(${TEST_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Test)
        set_target_properties(${TEST_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/Test)
        set_target_properties(${TEST_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/Test)
        set_target_properties(${TEST_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_BINARY_DIR}/Test)
        set_target_properties(${TEST_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_BINARY_DIR}/Test)
        gtest_discover_tests(${TEST_NAME}
                             WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/Test
                             TEST_LIST ${GTEST_LIST})
        #add test to target BuildAndTestAll
        add_dependencies(BuildAndTestAll ${TEST_NAME})
        #finish config
        message(STATUS "Succeed!")
    endif()
endfunction()
#example: create_gtest(TestName "${TEST_FILES}" "${SOURCE_FILES}" "${LIBS})
